﻿using System;
using System.Collections.Generic;
using System.Text;
using log4net;

namespace RollBackLib.src.core
{
    /// <summary>
    /// Manages a set of backup jobs
    /// </summary>
    public class JobManager
    {
        public enum DResult
        {
            GotException,
            LogMsg
        };
        public delegate int BackupDelegate(DResult dresult, int param2, object data);

        private Dictionary<BackupJob,Object> m_BackupJobMap = new Dictionary<BackupJob,Object>();

        /// <summary>
        /// List of backup jobs
        /// </summary>
        public List<BackupJob> m_BackupJobList {
            get;
            set; 
        }
        private static readonly ILog log = LogManager.GetLogger(typeof(JobManager));

        public string m_RootPath
        {
            get;
            set;
        }

        public JobManager()
        {
            m_BackupJobList = new List<BackupJob>();
        }

        /// <summary>
        /// Load the saved backup sets.
        /// </summary>
        public void LoadSavedBackupSets(string file, BackupDelegate cb)
        {
            try
            {
                if (m_RootPath == null)
                {
                    m_RootPath = file;
                }
                clearPreviouslyLoadedJobTabs();
                List<BackupJob> list = BackupJob.LoadBackupSets(file);

                foreach (BackupJob job in list)
                {
                    if (job != null)
                    {
                        job.resetJobSettings();
                        try
                        {
                            AddBackupJob(job, null);
                        }
                        catch (BackupException e)
                        {
                            if (cb != null)
                            {
                                int ret = cb(DResult.GotException, 0, e);
                                if (ret != 0)
                                {
                                    break;
                                }
                            }
                        }
                    }
                }
                m_RootPath = file;
                string msg = "Finished loading " + file + " with " + list.Count + " jobs.";
                cb(DResult.LogMsg,0,msg);
            }
            catch (Exception e)
            {
                cb(DResult.GotException,0, e);
            }
        }

        private void clearPreviouslyLoadedJobTabs()
        {
            lock (m_BackupJobList)
            {
                log.Debug("Clearing " + m_BackupJobList.Count + " items from job list");
                m_BackupJobList.Clear();
            }
        }

        public void AddBackupJob(BackupJob job, Object data)
        {
            lock (m_BackupJobList)
            {
                if (m_BackupJobMap.ContainsKey(job))
                {
                    throw new BackupException("Job with key name <" + job.GetKey() + "> already exists");
                }

                if (job.m_Id.m_Name.Length <= 0)
                {
                    throw new BackupException("Job name cannot be empty");
                }
                foreach (BackupJob j in m_BackupJobList)
                {
                    string key1 = j.m_Id.m_Name.ToString();
                    string key2 = job.m_Id.m_Name.ToString();
                    if (key1.Equals(key2, StringComparison.CurrentCultureIgnoreCase))
                    {
                        throw new BackupException("Job with name <" + key1 + "> already exists");
                    }
                }
                log.Info("Adding backup job " + job.GetKey());
                m_BackupJobList.Add(job);
                m_BackupJobMap[job] = data;
            }
        }

        public void removeBackupJob(BackupJob job)
        {
            lock (m_BackupJobList)
            {
                log.Debug("Removing backup job <" + job.GetKey() + ">");
                job.m_Deleted = true;
                m_BackupJobList.Remove(job);
                m_BackupJobMap.Remove(job);
            }
        }
    }
}
